import { DataType, JavaScriptType, LineBreak, SupportedProperties } from "@/constant";
import { IDataType, ITable } from "@/types";
import { upperFirstStrCase, typeFilter } from "@/util";

export const ModelTemplate = (modelOptions: ITable) => {
    const { name, columns } = modelOptions;
    const upperFirstName = upperFirstStrCase(name);
    return `
import { BaseAttributes } from '../../@types/sequelize'
import { DataTypes, Model } from 'sequelize'
import { sequelize } from '../../config/sequelizeBase'
import BaseColumn from '../base'

class ${upperFirstName} extends Model<BaseAttributes> {
${columns.reduce((prev, cur, index) => {
  const type = typeFilter(cur.type).toUpperCase();
  return prev + `    ${cur.name}${cur.notNull ? '' : '?'}: ${JavaScriptType[type]};${index === (columns.length - 1) ? '' : LineBreak}`;
}, '')}
}

${upperFirstName}.init(
  {
    ...BaseColumn,
${columns.reduce((prev, cur, index) => {
      return prev + `    ${cur.name}: { ${
          Object.keys(cur).reduce((_p, _c) => {
              if (SupportedProperties.includes(_c)) {
                if (_c === 'type') {
                  const type: IDataType = typeFilter(cur[_c]);
                  _p = _p + `${_c}: ${DataType[type]}, `
                } else {
                  _p = _p + `${_c}: ${typeof cur[_c] === 'string' ? `"${cur[_c]}"` : cur[_c]}, `
                }
              }
              return _p;
          }, '')
      }},${index === (columns.length - 1) ? '' : LineBreak}`;
    }, '')}
  },
  {
    tableName: '${name}',
    freezeTableName: true,
    sequelize,
  },
)

export default ${upperFirstName}
`;
}


export const ControllerTemplate = (controllerOptions: ITable) => {
  const { name } = controllerOptions;
  const upperFirstName = upperFirstStrCase(name);
  return `
import { Context } from 'koa'
import BaseController from '../base'
import service from '../../services/module/${name}'
import Decorator from '../../utils/decorator'

export default class ${upperFirstName}Controller extends BaseController {

  @Decorator.Get
  public static async get${upperFirstName}List(ctx: Context, params) {
    return await service.get${upperFirstName}List(ctx, params)
  }
}
`;
}


export const ServiceTemplate = (serviceOptions: ITable) => {
  const { name } = serviceOptions;
  const upperFirstName = upperFirstStrCase(name);
  return `
import { Context } from 'koa'
import BaseService from '../base'

export default class ${upperFirstName}Service extends BaseService {

  public static async get${upperFirstName}List(ctx: Context, params) {
    // write something...
    return []
  }
}
`;
}


export const RouterTemplate = (table: ITable) => {
  const { name } = table;
  const upperFirstName = upperFirstStrCase(name);
  return `
  {
    moduleName: '${upperFirstName}',
    paths: [
      {
        path: '/get${upperFirstName}List',
        fnName: '/get${upperFirstName}List',
        method: Methods.GET,
      },
    ],
  },`
}